<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>热成像</title>
    <!-- <script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script> -->
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script> -->

    <script src="./xlsx.full.min.js"></script>

    <style>
      #heatmapCanvas {
        /* border: 1px solid black; */
      }
    </style>
  </head>
  <body>
    <button onclick="chuNenFx()">储能数据分析</button>      
    <input type="file" id="fileInput" />
    <input type="number" id="reLiNum" placeholder="输入数字" />
    <button onclick="getValue()">获取值</button>  
    <button onclick="showMaxTemperature()">显示最高温度</button>
    <button onclick="showMinTemperature()">显示最低温度</button>
    <br />
    <button onclick="highlightMaxTemperature()">标记最高温度</button>
    <button onclick="highlightMinTemperature()">标记最低温度</button>

    <canvas id="heatmapCanvas"></canvas>
    <script>
      document
        .getElementById("fileInput")
        .addEventListener("change", handleFileSelect, false);
      // 双线性插值算法
      var newData = [];
      function processFile() {
        const fileInput = document.getElementById("fileInput");
        const file = fileInput.files[0];
        const reader = new FileReader();
        reader.onload = function (event) {
          const data = new Uint8Array(event.target.result);
          const workbook = XLSX.read(data, { type: "array" });
          const sheetName = workbook.SheetNames[0];
          const worksheet = workbook.Sheets[sheetName];
          const csv = XLSX.utils.sheet_to_csv(worksheet);
          const arrayData = csvToArray(csv);
          const interpolatedData = interpolate22(arrayData, 480, 640); // 增加到 240, 320 的分辨率   1440, 1920 --  384, 512
          //   console.log("Interpolated", interpolatedData);
          const szNew = interpolatedData
            .map((row) => row.map((cell) => Math.round(cell)))
            .map(
              (row) => row.filter((cell) => cell !== 0) // 过滤掉值为 0 的元素
            );
          console.log(szNew);
          newData = szNew;
        };
        reader.readAsArrayBuffer(file);
      }

      function interpolate22(data, newRows, newCols) {
        const rows = data.length;
        const cols = data[0].length;
        const interpolatedData = Array.from({ length: newRows }, () =>
          Array(newCols).fill(0)
        );

        for (let i = 0; i < newRows; i++) {
          for (let j = 0; j < newCols; j++) {
            const xRatio = (j / (newCols - 1)) * (cols - 1);
            const yRatio = (i / (newRows - 1)) * (rows - 1);
            const x0 = Math.floor(xRatio);
            const x1 = Math.min(x0 + 1, cols - 1);
            const y0 = Math.floor(yRatio);
            const y1 = Math.min(y0 + 1, rows - 1);

            const q11 = data[y0][x0];
            const q21 = data[y0][x1];
            const q12 = data[y1][x0];
            const q22 = data[y1][x1];

            const r1 = (x1 - xRatio) * q11 + (xRatio - x0) * q21;
            const r2 = (x1 - xRatio) * q12 + (xRatio - x0) * q22;

            interpolatedData[i][j] = (y1 - yRatio) * r1 + (yRatio - y0) * r2;
          }
        }

        return interpolatedData;
      }

      // 最大值

      function getMaxTemperature(data) {
        let maxTemp = -Infinity;
        for (const row of data) {
          for (const temp of row) {
            if (temp > maxTemp) {
              maxTemp = temp;
            }
          }
        }
        return maxTemp;
      }
      //   插值算法封装
      function interpolate(data, newRows, newCols) {
        const rows = data.length;
        const cols = data[0].length;
        const x = Array.from({ length: cols }, (_, i) => i);
        const y = Array.from({ length: rows }, (_, i) => i);

        const interpolatedData = Array.from({ length: newRows }, (_, i) => {
          return Array.from({ length: newCols }, (_, j) => {
            const xRatio = (j / (newCols - 1)) * (cols - 1);
            const yRatio = (i / (newRows - 1)) * (rows - 1);
            const x0 = Math.floor(xRatio);
            const x1 = Math.min(x0 + 1, cols - 1);
            const y0 = Math.floor(yRatio);
            const y1 = Math.min(y0 + 1, rows - 1);

            const q11 = data[y0][x0];
            const q21 = data[y0][x1];
            const q12 = data[y1][x0];
            const q22 = data[y1][x1];

            const r1 = (x1 - xRatio) * q11 + (xRatio - x0) * q21;
            const r2 = (x1 - xRatio) * q12 + (xRatio - x0) * q22;

            return (y1 - yRatio) * r1 + (yRatio - y0) * r2;
          });
        });

        return interpolatedData;
      }
      function csvToArray(text) {
        return text.split("\n").map((row) => row.split(",").map(Number));
      }

      var maxTemperature = [];

      // 最小值
      function getMinTemperature(data) {
        let minTemp = Infinity;
        for (const row of data) {
          for (const temp of row) {
            if (temp < minTemp) {
              minTemp = temp;
            }
          }
        }
        return minTemp;
      }
      // 显示最低温度
      function showMinTemperature() {
        const minTemperature = getMinTemperature(maxTemperature);
        alert(`最低温度是: ${minTemperature / 100}°C`);
      }

      function showMaxTemperature() {
        if (maxTemperature.length > 0) {
          const maxTempe = getMaxTemperature(maxTemperature);
          alert(`最高温度是: ${maxTempe / 100}°C`);
        } else {
          alert(`最高温度是: 请先上传数据`);
        }
      }
      // 封装双线性插值算法
      function bilinearInterpolate(x, y, values) {
        const x1 = Math.floor(x);
        const y1 = Math.floor(y);
        const x2 = Math.ceil(x);
        const y2 = Math.ceil(y);

        const Q11 = values[y1] ? values[y1][x1] : 0;
        const Q12 = values[y1] ? values[y1][x2] : 0;
        const Q21 = values[y2] ? values[y2][x1] : 0;
        const Q22 = values[y2] ? values[y2][x2] : 0;

        const xFraction = x - x1;
        const yFraction = y - y1;

        const R1 = Q11 * (1 - xFraction) + Q12 * xFraction;
        const R2 = Q21 * (1 - xFraction) + Q22 * xFraction;

        return R1 * (1 - yFraction) + R2 * yFraction;
      }
      // 获取excel数据
      async function handleFileSelect(event, json) {
        await processFile();
        const file = event.target.files[0];
        // console.log("=====>>>", file);

        if (!file) return;

        const reader = new FileReader();
        reader.onload = function (e) {
          const data = new Uint8Array(e.target.result);
          const workbook = XLSX.read(data, { type: "array" });

          // Assuming you want to process the first sheet
          const sheetName = workbook.SheetNames[0];
          const worksheet = workbook.Sheets[sheetName];
          //   const json = XLSX.utils.sheet_to_json(worksheet, {
          //     header: 1,
          //     defval: 0,
          //   });
          // Default values for empty cells

          // Convert data to 2D array
          //   console.log("===========json=====================", json);
          const dataArray = newData.map((row) =>
            row.map((cell) => parseFloat(cell) || 0)
          );
          //   console.log("Data Array:", dataArray);
          maxTemperature = dataArray;
          //   console.log("=workbook===" + maxTemperature);

          drawHeatmap(dataArray);
        };
        reader.readAsArrayBuffer(file);
      }

      // 插值算法
      const canvas = document.getElementById("heatmapCanvas");
      //   const cellSize = 10; // 原始单元格大小
      let newCellSize = 1; // 插值后的单元格大小
      function getValue() {
        const inputElement = document.getElementById("reLiNum");
        const value = inputElement.value; // 获取输入的值
        newCellSize = value;
        drawHeatmap(maxTemperature); // 重新绘制热力图
      }
      //   页面跳转
      function chuNenFx() {
        window.location.replace("./boxEchars.html");
      }

      //   绘制热力图
      function drawHeatmap(dataArray) {
        const width = dataArray[0].length;
        const height = dataArray.length;

        // 计算新画布的宽度和高度
        const canvasWidth = width * newCellSize;
        const canvasHeight = height * newCellSize;
        // Adjust canvas size
        canvas.width = canvasWidth; // Scale width
        canvas.height = canvasHeight; // Scale height

        const ctx = canvas.getContext("2d");
        const imageData = ctx.createImageData(canvasWidth, canvasHeight);

        // 查找归一化的最小值和最大值
        let min = Infinity;
        let max = -Infinity;
        dataArray.flat().forEach((value) => {
          if (value < min) min = value;
          if (value > max) max = value;
        });

        // 生成热力图
        for (let y = 0; y < canvasHeight; y++) {
          for (let x = 0; x < canvasWidth; x++) {
            const dataX = x / newCellSize;
            const dataY = y / newCellSize;

            const value = bilinearInterpolate(dataX, dataY, dataArray);

            // const value = dataArray[y][x];
            const normalizedValue = (value - min) / (max - min);
            // for (let dy = 0; dy < cellSize; dy++) {
            //     for (let dx = 0; dx < cellSize; dx++) {
            //         const index = ((y * cellSize + dy) * canvas.width + (x * cellSize + dx)) * 4;
            //         const color = getHeatmapColor(normalizedValue);

            //         imageData.data[index] = color[0];
            //         imageData.data[index + 1] = color[1];
            //         imageData.data[index + 2] = color[2];
            //         imageData.data[index + 3] = 255;
            //     }
            // }

            // // 获取颜色值
            const color = getHeatmapColor(normalizedValue);
            // 设置画布上的像素颜色
            const index = (y * canvasWidth + x) * 4;
            imageData.data[index] = color[0]; // Red
            imageData.data[index + 1] = color[1]; // Green
            imageData.data[index + 2] = color[2]; // Blue
            imageData.data[index + 3] = 255; // Alpha
          }
        }
        // console.log("imageDat", imageData);
        ctx.putImageData(imageData, 0, 0);
      }

      // 找到最高温度及其位置
      function getMaxTemperatureInfo(isMax) {
        let extremeTemp = isMax ? -Infinity : Infinity;
        let position = { row: 0, col: 0 };

        maxTemperature.forEach((row, rowIndex) => {
          row.forEach((temp, colIndex) => {
            if (
              (isMax && temp > extremeTemp) ||
              (!isMax && temp < extremeTemp)
            ) {
              extremeTemp = temp;
              position = { row: rowIndex, col: colIndex };
            }
          });
        });

        return { extremeTemp, position };
      }

      // 找到最高温度及其位置
      //   function getMaxTemperatureInfo() {
      //     let maxTemp = -Infinity;
      //     let position = { row: 0, col: 0 };
      //     maxTemperature.forEach((row, rowIndex) => {
      //       row.forEach((temp, colIndex) => {
      //         if (temp > maxTemp) {
      //           maxTemp = temp;
      //           position = { row: rowIndex, col: colIndex };
      //         }
      //       });
      //     });
      //     return { maxTemp, position };
      //   }

      // 标记最高温度
      function highlightMaxTemperature() {
        const { extremeTemp, position } = getMaxTemperatureInfo(true);
        drawHeatmap(maxTemperature); // 重新绘制热力图
        const ctx = canvas.getContext("2d");

        // 绘制标记
        ctx.strokeStyle = "yellow";
        ctx.lineWidth = 30;
        ctx.beginPath();
        const x = position.col * newCellSize + newCellSize / 2;
        const y = position.row * newCellSize + newCellSize / 2;
        ctx.arc(x, y, newCellSize / 4, 0, 2 * Math.PI);
        ctx.stroke();
        ctx.fillStyle = "yellow";
        ctx.fill();
        // alert(`最高温度是: ${extremeTemp/100}°C`);
        // 显示温度值
        ctx.fillStyle = "black";
        ctx.font = "12px Arial";
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.fillText(`${extremeTemp / 100}°C`, x, y);
      }
      // 标记最低温度
      function highlightMinTemperature() {
        const { extremeTemp, position } = getMaxTemperatureInfo(false);
        drawHeatmap(maxTemperature); // 重新绘制热力图
        const ctx = canvas.getContext("2d");

        // 绘制标记
        ctx.strokeStyle = "green";
        ctx.lineWidth = 30;
        ctx.beginPath();
        const x = position.col * newCellSize + newCellSize / 2;
        const y = position.row * newCellSize + newCellSize / 2;
        ctx.arc(x, y, newCellSize / 4, 0, 2 * Math.PI);
        ctx.stroke();
        ctx.fillStyle = "green";
        ctx.fill();
        // alert(`最低温度是: ${extremeTemp/100}°C`);
        // 显示温度值
        ctx.fillStyle = "white";
        ctx.font = "12px Arial";
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.fillText(`${extremeTemp / 100}°C`, x, y);
      }

      function getHeatmapColor(value) {
        // 从蓝色到红色的简单热图颜色渐变
        const r = Math.min(255, Math.max(0, Math.floor(255 * value)));
        const g = Math.min(255, Math.max(0, Math.floor(255 * (1 - value))));
        const b = 0;
        return [r, g, b];
      }
    </script>
  </body>
</html>
